#!/usr/bin/env python3
"""
加密服务 - 提供AES-256加密和JWT签名功能
"""

import base64
import json
from datetime import datetime, timedelta, timezone
from typing import Any

from jose import jwt
from jose.exceptions import ExpiredSignatureError, JWTError
from cryptography.fernet import Fernet, InvalidToken

from app.core.config import settings


class CryptoService:
    """加密服务类"""

    def __init__(self):
        """初始化加密服务"""
        # 确保密钥格式正确
        if len(settings.AES_ENCRYPTION_KEY) != 44:
            raise ValueError("AES加密密钥必须为44字符的base64编码字符串")

        # 初始化Fernet加密器
        self.fernet = Fernet(settings.AES_ENCRYPTION_KEY.encode())

    def encrypt_data(self, data: dict[str, Any]) -> str:
        """
        AES-256加密数据

        Args:
            data: 要加密的数据字典

        Returns:
            str: base64编码的加密数据
        """
        try:
            # 转换为JSON字符串并加密
            json_data = json.dumps(data, ensure_ascii=False)
            encrypted_data = self.fernet.encrypt(json_data.encode("utf-8"))
            return base64.urlsafe_b64encode(encrypted_data).decode("utf-8")

        except Exception as e:
            raise ValueError(f"数据加密失败: {str(e)}")

    def decrypt_data(self, encrypted_data: str) -> dict[str, Any]:
        """
        AES-256解密数据

        Args:
            encrypted_data: base64编码的加密数据

        Returns:
            dict[str, Any]: 解密后的数据字典
        """
        """
        AES-256解密数据

        Args:
            encrypted_data: base64编码的加密数据

        Returns:
            dict[str, Any]: 解密后的数据字典
        """
        try:
            # 解码并解密
            decoded_data = base64.urlsafe_b64decode(encrypted_data.encode("utf-8"))
            decrypted_data = self.fernet.decrypt(decoded_data).decode("utf-8")
            return json.loads(decrypted_data)

        except InvalidToken:
            raise ValueError("无效的加密令牌")
        except Exception as e:
            raise ValueError(f"数据解密失败: {str(e)}")

    def create_jwt_token(self, payload: dict[str, Any], expires_minutes: int = 30) -> str:
        """
        创建JWT令牌

        Args:
            payload: 令牌负载
            expires_minutes: 过期时间（分钟）

        Returns:
            str: JWT令牌
        """
        try:
            # 添加过期时间
            expire = datetime.now(timezone.utc) + timedelta(minutes=expires_minutes)
            payload.update({"exp": expire})

            # 生成令牌
            token = jwt.encode(payload, settings.JWT_SECRET_KEY, algorithm="HS256")
            return token

        except Exception as e:
            raise ValueError(f"JWT令牌创建失败: {str(e)}")

    def verify_jwt_token(self, token: str) -> dict[str, Any]:
        """
        验证JWT令牌

        Args:
            token: JWT令牌

        Returns:
            dict[str, Any]: 解码后的负载
        """
        try:
            payload = jwt.decode(token, settings.JWT_SECRET_KEY, algorithms=["HS256"])
            return payload

        except ExpiredSignatureError:
            raise ValueError("令牌已过期")
        except JWTError:
            raise ValueError("无效的令牌")
        except Exception as e:
            raise ValueError(f"JWT令牌验证失败: {str(e)}")


# 全局加密服务实例
crypto_service = CryptoService()
